Houdiniメモ : VEX : 座標を回転してX軸上に乗せる
方法1 : dihedralで回転させる(編集中)
VEX関数のdihedralを利用することで、あるベクトルから別のベクトルへ回転させるような行列を求めることができます。
方法2 : 回転行列で回転させる
ポイントから角度 $ \theta_1, \theta_2 を求め、回転行列を利用して回転させる方法
$ \theta_1 : ラインをXZ平面へ射影してできる線と、X軸のなす角
$ \theta_2 : ラインをXZ平面へ射影してできる線と、ラインがなす角
■ 回転行列
Y軸周りに $ \theta_1 回転させる行列 $ M_Y
$ M_Y = \begin{pmatrix} cos \theta_1 & 0 & -sin \theta_1 \\ 0 & 1 & 0 \\\ sin \theta_1 & 0 & cos \theta_1 \end{pmatrix}
Z軸周りに $ \theta_2 回転させる行列 $ M_Z
$ M_Z = \begin{pmatrix} cos \theta_2 & -sin \theta_2 & 0 \\ sin \theta_2 & cos \theta_2 & 0 \\\ 0 & 0 & 1 \end{pmatrix}
■ 行列を利用した回転
回転前、 回転後の座標ベクトルをそれぞれ $ \begin{pmatrix} x_1 \\ y_1 \\ z_1 \end{pmatrix}, \begin{pmatrix} x_2 \\ y_2 \\ z_2 \end{pmatrix} と置いた場合、今回の回転操作は以下のようになります。
$ \begin{pmatrix} x_2 \\ y_2 \\ z_2 \end{pmatrix} = M_Z \cdot M_Y \cdot \begin{pmatrix} x_2 \\ y_2 \\ z_2 \end{pmatrix}
■コード
上記の回転操作をVEXで実装すると以下のようになります。
code:VEX(c)
// アトリビュートから座標を取得
vector p = @P;
// 直線のxz平面への射影とx軸がなす角
float theta1 = atan2(p.z, p.x);
// 直線のxy平面への射影
float bottom = length(set(p.x, 0, p.z));
// 射影と直線がなす角
float theta2 = atan2(p.y, bottom);
// Y軸 まわり theta1 回転(ラインはXZ平面上に乗る)
matrix3 rotY = matrix3(set(
set(cos(theta1), 0, -sin(theta1)),
set(0, 1, 0 ),
set(sin(theta1), 0, cos(theta1))
));
// Z軸 まわり theta2 回転(ラインはX軸上に乗る)
matrix3 rotZ = matrix3(set(
set(cos(theta2), -sin(theta2), 0),
set(sin(theta2), cos(theta2), 0 ),
set(0, 0, 1)
));
// 座標の回転
p *= rotY; // Y軸回転
p *= rotZ; // Z軸回転
// アトリビュートへ座標を戻す
@P = p;